
#include <Inklude/ikCSerialComm.h>
#include <tchar.h>

using namespace Inklude;

void _inklude_serial_comm_print_error_message(const char* customMessage)
{
    printf(customMessage);
    printf("\n");
    TCHAR lastError[1024];
    FormatMessage ( FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
                    NULL,
                    GetLastError(),
                    MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
                    lastError,
                    1024,
                    NULL);
    _tprintf(lastError);
    printf("\n");
    printf("\n");
}


ikCSerialComm::ikCSerialComm()
{
    m_hSerial = NULL;
}

ikCSerialComm::~ikCSerialComm()
{
}

bool ikCSerialComm::Create(Inklude::ikCString& strComName, unsigned int BaudRate)
{
    m_hSerial = CreateFile(strComName.c_tstr(),
                           GENERIC_READ | GENERIC_WRITE,
                           0,
                           0,
                           OPEN_EXISTING,
                           FILE_ATTRIBUTE_NORMAL,
                           0);

    
    if (INVALID_HANDLE_VALUE == m_hSerial)
    {
        _inklude_serial_comm_print_error_message("Error : File Creation");
        return false;
    }

    DCB dcbSerialParams = {0};
    dcbSerialParams.DCBlength = sizeof(dcbSerialParams);
    
    if (!GetCommState(m_hSerial, &dcbSerialParams)) 
    {
        _inklude_serial_comm_print_error_message("Error : GetCommState");
        CloseHandle(m_hSerial);
        return false;
    }

    dcbSerialParams.BaudRate=BaudRate;
    dcbSerialParams.ByteSize=8;
    dcbSerialParams.StopBits=ONESTOPBIT;
    dcbSerialParams.Parity=NOPARITY;
    if(!SetCommState(m_hSerial, &dcbSerialParams))
    {
        _inklude_serial_comm_print_error_message("Error : SetCommState");
        CloseHandle(m_hSerial);
        return false;
    }


    COMMTIMEOUTS timeouts={0};
    timeouts.ReadIntervalTimeout=50;
    timeouts.ReadTotalTimeoutConstant=50;
    timeouts.ReadTotalTimeoutMultiplier=10;
    timeouts.WriteTotalTimeoutConstant=50;
    timeouts.WriteTotalTimeoutMultiplier=10;
    
    if(!SetCommTimeouts(m_hSerial, &timeouts))
    {
        _inklude_serial_comm_print_error_message("Error : timeout setting");
        CloseHandle(m_hSerial);
        return false;
    }

    return true;
}

bool ikCSerialComm::Read(char* Buffer, unsigned int ReadSize, unsigned int Offset)
{
    DWORD _dwBytesRead = 0;
    ReadFile(m_hSerial, Buffer + Offset, ReadSize, &_dwBytesRead, NULL);
    return (_dwBytesRead > 0 || _dwBytesRead == ReadSize);
}

bool ikCSerialComm::Write(char* Buffer, unsigned int WriteSize, unsigned int Offset)
{
    DWORD _dwBytesWritten = 0;
    WriteFile(m_hSerial, Buffer + Offset, WriteSize, &_dwBytesWritten, NULL);
    return (_dwBytesWritten == WriteSize);
}

bool ikCSerialComm::WriteString(Inklude::ikCString& strData)
{
    DWORD _dwBytesWritten = 0;
    WriteFile(m_hSerial, strData.c_str(), strData.Length(), &_dwBytesWritten, NULL);
    return ( strData.Length() == _dwBytesWritten );
}

